﻿using DotNetCore.CAP;
using Handday.Erp.Transfer.Entities;
using Handday.Erp.Transfer.Message;
using Handday.Erp.Transfer.Models.Cap;
using Handday.Erp.Transfer.Models.EightTradingSource;
using Handday.Erp.Transfer.Repositories;
using HandDay.Framework.Common.Services;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
using System.Threading.Tasks;
using MapsterMapper;
using Handday.Erp.Core;

namespace Handday.Erp.Transfer.Services.Imp
{
    /// <summary>
    /// 8项交易数据服务
    /// </summary>
    public class EightTradingService : IEightTradingService
    {
        private readonly ICapPublisher _publisher;
        private readonly CurrentInfo _currentInfo;
        private readonly IMapper _mapper;
        private readonly IUnitOfWorkManager _unitOfWorkManager;
        private readonly JsonSerializerOptions _jsonSerializerOptions;
        private readonly IEightTradingSourceRepository _eightTradingSourceRepository;
        private readonly IEightTradingDapperRepository _eightTradingDapperRepository;
        private readonly IEightTradingTransferRepository _eightTradingTransferRepository;

        /// <summary>
        /// ctor
        /// </summary>
        public EightTradingService(
            ICapPublisher publisher,
            CurrentInfo currentInfo,
            IMapper mapper,
            IUnitOfWorkManager unitOfWorkManager,
            IEightTradingSourceRepository eightTradingSourceRepository,
            IEightTradingDapperRepository eightTradingDapperRepository,
            IEightTradingTransferRepository eightTradingTransferRepository)
        {
            _publisher = publisher;
            _currentInfo = currentInfo;
            _mapper = mapper;
            _unitOfWorkManager = unitOfWorkManager;
            _eightTradingSourceRepository = eightTradingSourceRepository;
            _jsonSerializerOptions = new JsonSerializerOptions { WriteIndented = false };
            _eightTradingDapperRepository = eightTradingDapperRepository;
            _eightTradingTransferRepository = eightTradingTransferRepository;
        }

        /// <summary>
        /// 接收Erp数据
        /// </summary>
        public async Task<ServiceResult> ReceiveAsync(List<EightTradingSourceAddDto> list)
        {
            var msg = new CapMsg
            {
                CorpId = _currentInfo.CorpId,
                FeatureType = Enum.ErpFeatureTypeEnum.EightTrading,
                JsonData = JsonSerializer.Serialize(list, _jsonSerializerOptions)
            };
            await _publisher.PublishAsync(MessageConst.ERP_SOURCE_COMMON_SUBSCRIBE, msg);
            return ServiceResult.Succeed();
        }

        /// <summary>
        /// 获取最大记账日期
        /// </summary>
        /// <param name="corpId">企业编号</param>
        public async Task<ServiceResult<EightTradingAccountTimeDto>> GetMaxAccountTimeAsync(ulong corpId)
        {
            var time = _eightTradingSourceRepository.Max(m => m.AccountTime);
            if (time == null)
            {
                time = new DateTimeOffset(DateTimeOffset.Now.Year, 1, 1, 0, 0, 0, TimeSpan.FromHours(8));
            }

            return await Task.FromResult(ServiceResult.Succeed<EightTradingAccountTimeDto>(new EightTradingAccountTimeDto { CorpId = corpId, AccountTime = time }));
        }

        /// <summary>
        /// 清除数据
        /// </summary>
        /// <param name="time">清除日期</param>
        public async Task<ServiceResult> ClearAsync(DateTimeOffset? time)
        {
            if (time.HasValue && time != DateTimeOffset.MinValue)
            {
                using (var uow = _unitOfWorkManager.Begin())
                {
                    await _eightTradingSourceRepository.DeleteAsync(m => m.InputTime <= time);
                    await _eightTradingTransferRepository.DeleteAsync(m => m.Year < time.Value.Year || (m.Year == time.Value.Year && m.Month <= time.Value.Month));
                    await uow.CompleteAsync();
                }
            }

            return ServiceResult.Succeed();
        }

        /// <summary>
        /// 初始化表
        /// </summary>
        /// <param name="corpId">企业编号</param>
        public async Task<ServiceResult> InitTableAsync(ulong corpId)
        {
            await _eightTradingDapperRepository.InitTableAsync(corpId);
            return ServiceResult.Succeed();
        }

        /// <summary>
        /// 源数据列表请求
        /// </summary>
        public async Task<List<EightTradingSourceDto>> PageListAsync(EightTradingSourceRequestDto request)
        {
            SetListRequest(request);
            var list = await GetQueryable(request).ToListAsync();
            return _mapper.Map<List<EightTradingSourceDto>>(list);
        }

        #region private methods

        /// <summary>
        /// 源数据列表请求参数设置
        /// </summary>
        private void SetListRequest(EightTradingSourceRequestDto request)
        {
            var curTime = DateTimeOffset.Now;
            if (!request.StartTime.HasValue)
            {
                request.StartTime = new DateTimeOffset(curTime.Year, 1, 1, 0, 0, 0, TimeSpan.FromHours(8));
            }

            if (!request.EndTime.HasValue)
            {
                request.EndTime = curTime;
            }
        }

        /// <summary>
        /// 获取列表queryable
        /// </summary>
        /// <returns></returns>
        private IQueryable<EightTradingSource> GetQueryable(EightTradingSourceRequestDto request)
        {
            var queryable = _eightTradingSourceRepository.Where(m => m.InputTime >= request.StartTime && m.InputTime <= request.EndTime);
            if (request.CustomId.GetValueOrDefault() > 0)
            {
                queryable = queryable.Where(m => m.CustomId == request.CustomId.GetValueOrDefault());
            }

            queryable = queryable.Skip((request.PageIndex - 1) * request.PageSize).Take(request.PageSize);

            return queryable;
        }
        #endregion
    }
}